package com.example.wangzh.developkit.utils.encrypt;

import android.util.Base64;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {
	public final static String TRANSFER_SEED = "esWES65d181GJarv";  //加密seed
	public final static String TRANSFER_KEY = "esbcf4laWE9pfesb";  //加密key

	// 算法参数 16字节
	private static final String IV = "~e#$1-+=@%^&*(w)";
	public static final String CHARSET = "UTF-8";
	private static final String ALGORITHM = "AES";
	/** 算法/模式/填充 **/
	private static final String CIPHER_MODE = "AES/CBC/PKCS5Padding";

	/**
	 * 加密
	 * 
	 * @param seed
	 *            用户口令，长度固定为16字节（16个英文字符）
	 * @param cleartext
	 *            明文
	 * @return 密文
	 * @throws Exception
	 */
	public static String encrypt(String seed, String cleartext)
			throws Exception {
		IvParameterSpec zeroIv = new IvParameterSpec(IV.getBytes(CHARSET));
		SecretKeySpec key = new SecretKeySpec(seed.getBytes(CHARSET), ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
		cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
		byte[] encryptedData = cipher.doFinal(cleartext.getBytes(CHARSET));

		return Base64.encodeToString(encryptedData, Base64.NO_WRAP);
//		return Base64.encodeBytes(encryptedData);
	}

	public static byte[] encrypt(String seed, byte[] source) throws Exception {
		IvParameterSpec zeroIv = new IvParameterSpec(IV.getBytes(CHARSET));
		SecretKeySpec key = new SecretKeySpec(seed.getBytes(CHARSET), ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
		cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
		byte[] encryptedData = cipher.doFinal(source);

		return Base64.encode(encryptedData, Base64.NO_WRAP);
//		return Base64.encodeBytesToBytes(encryptedData);
	}

	/**
	 * 解密
	 * 
	 * @param seed
	 *            用户口令，长度固定为16字节（16个英文字符）
	 * @param encrypted
	 *            密文
	 * @return 明文
	 * @throws Exception
	 */
	public static String decrypt(String seed, String encrypted)
			throws Exception {
//		byte[] byteMi = Base64.decode(encrypted);

		byte[] byteMi = Base64.decode(encrypted, Base64.NO_WRAP);
		IvParameterSpec zeroIv = new IvParameterSpec(IV.getBytes(CHARSET));
		SecretKeySpec key = new SecretKeySpec(seed.getBytes(CHARSET), ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
		cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
		byte[] decryptedData = cipher.doFinal(byteMi);

		return new String(decryptedData, CHARSET);
	}

	public static String decrypt(String seed, byte[] encrypted)
			throws Exception {
//		byte[] byteMi = Base64.decode(encrypted);

		byte[] byteMi = Base64.decode(encrypted, Base64.NO_WRAP);
		IvParameterSpec zeroIv = new IvParameterSpec(IV.getBytes(CHARSET));
		SecretKeySpec key = new SecretKeySpec(seed.getBytes(CHARSET), ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
		cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
		byte[] decryptedData = cipher.doFinal(byteMi);

		return new String(decryptedData, CHARSET);
	}

//	public static void main(String[] args) {
//		try {
//			String seed = "@2:?~cde#gh)k!,=";
//			String cleartext = "12345ABCDE我";
//			System.out.println("cleartext: " + cleartext);
//			String encrypted = AESUtil.encrypt(seed, cleartext);
//			System.out.println("加密: " + encrypted);
//			System.out.println("解密: " + AESUtil.decrypt(seed, encrypted));
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	// MD5加密
	public static String toMd5(byte[] bytes) {
		try {
			MessageDigest algorithm = MessageDigest.getInstance("MD5");
			algorithm.reset();
			algorithm.update(bytes);

			return toHexString(algorithm.digest());
//			return toHexString(algorithm.digest(), "");
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
	}

	public static String toMD5(String str) {
		try {
			// 生成一个MD5加密计算摘要
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 计算md5函数
			md.update(str.getBytes());
			// digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
			// BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
			return new BigInteger(1, md.digest()).toString(16);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String toHexString(byte[] buffer) {
		StringBuffer sb = new StringBuffer();
		String s = null;
		for (int i = 0; i < buffer.length; i++) {
			s = Integer.toHexString(buffer[i] & 0xff);
			System.out.println(s);
			if (s.length() < 2)
				sb.append('0');
			sb.append(s);
		}
		return sb.toString();
	}
}
